package pers.adogs.novelboot.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import org.springframework.scheduling.annotation.EnableAsync;
import pers.adogs.novelboot.core.common.constant.ErrorCodeEnum;
import pers.adogs.novelboot.core.common.exception.BusinessException;
import pers.adogs.novelboot.core.common.resp.RestResp;
import pers.adogs.novelboot.core.constant.DatabaseConsts;
import pers.adogs.novelboot.core.constant.SystemConfigConsts;
import pers.adogs.novelboot.dao.entity.UserInfo;
import pers.adogs.novelboot.dao.mapper.UserInfoMapper;
import pers.adogs.novelboot.dto.resp.VerifyCodeRespDto;
import pers.adogs.novelboot.manager.message.VerifyCodeMailSender;
import pers.adogs.novelboot.manager.redis.VerifyCodeManager;
import pers.adogs.novelboot.service.ResourceService;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import javax.imageio.ImageIO;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

/**
 * 资源（图片/视频/文档）相关服务实现类
 *
 * @author adogs
 */
@Service
@RequiredArgsConstructor
@EnableAsync(proxyTargetClass = true)
@Slf4j
public class ResourceServiceImpl implements ResourceService {


    private final VerifyCodeManager verifyCodeManager;

    private final VerifyCodeMailSender verifyCodeMailSender;

    private final UserInfoMapper userInfoMapper;

    @Value("${novel.file.upload.path}")
    private String fileUploadPath;

    @Override
    public RestResp<VerifyCodeRespDto> getVerifyCode(String email) throws IOException {

        // 校验邮箱是否已注册
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(DatabaseConsts.UserInfoTable.COLUMN_USERNAME,email)
                .last(DatabaseConsts.SqlEnum.LIMIT_1.getSql());
        if (userInfoMapper.selectCount(queryWrapper) > 0) {
            // 邮箱已注册
            throw new BusinessException(ErrorCodeEnum.USER_NAME_EXIST);
        }

        String sessionId = IdWorker.get32UUID();
        String code=verifyCodeManager.getVerifyCode(sessionId);
        verifyCodeMailSender.sendMessage(email,code);
        log.info("开始返回sessionID");
        return RestResp.ok(VerifyCodeRespDto.builder()
                .sessionId(sessionId)
                .build());
    }

    @SneakyThrows
    @Override
    public RestResp<String> uploadImage(MultipartFile file) {
        LocalDateTime now = LocalDateTime.now();
        String savePath =
            SystemConfigConsts.IMAGE_UPLOAD_DIRECTORY
                + now.format(DateTimeFormatter.ofPattern("yyyy")) + File.separator
                + now.format(DateTimeFormatter.ofPattern("MM")) + File.separator
                + now.format(DateTimeFormatter.ofPattern("dd"));
        String oriName = file.getOriginalFilename();
        assert oriName != null;
        String saveFileName = IdWorker.get32UUID() + oriName.substring(oriName.lastIndexOf("."));
        File saveFile = new File(fileUploadPath + savePath, saveFileName);
        if (!saveFile.getParentFile().exists()) {
            boolean isSuccess = saveFile.getParentFile().mkdirs();
            if (!isSuccess) {
                throw new BusinessException(ErrorCodeEnum.USER_UPLOAD_FILE_ERROR);
            }
        }
        file.transferTo(saveFile);
        if (Objects.isNull(ImageIO.read(saveFile))) {
            // 上传的文件不是图片
            Files.delete(saveFile.toPath());
            throw new BusinessException(ErrorCodeEnum.USER_UPLOAD_FILE_TYPE_NOT_MATCH);
        }
        return RestResp.ok(savePath + File.separator + saveFileName);
    }

}
